// 引入其他类
import Food from "./Food";
import Snake from "./Snake";
import ScorePanel from "./ScorePanel";

// 游戏的控制器，控制其他的所有类
class GameControl {
    // 定义三个属性
    // 蛇
    snake: Snake;
    // 食物
    food: Food;
    // 计分牌
    scorePanel: ScorePanel;

    // 创建一个属性来存储蛇的移动方向（也是按键的方向）
    direction: string = "";

    // 创建一个属性用来记录游戏是否结束
    isLive: boolean = true;

    // 操作按键
    topBtn: HTMLElement;
    bottomBtn: HTMLElement;
    leftBtn: HTMLElement;
    rightBtn: HTMLElement;

    constructor() {
        this.snake = new Snake();
        this.food = new Food();
        this.scorePanel = new ScorePanel(10, 2);

        this.topBtn = document.getElementById('top')!;
        this.bottomBtn = document.getElementById('bottom')!;
        this.leftBtn = document.getElementById('left')!;
        this.rightBtn = document.getElementById('right')!;

        this.init();
    }

    // 初始化游戏
    init() {
        // 重置食物位置
        this.food.change();
        // 绑定键盘事件
        document.addEventListener("keydown", this.keydownHandler.bind(this));
        this.topBtn.addEventListener("click", () => {
            this.keydownHandler({key: "ArrowUp"})
        })
        this.bottomBtn.addEventListener("click", () => {
            this.keydownHandler({key: "ArrowDown"})
        })
        this.leftBtn.addEventListener("click", () => {
            this.keydownHandler({key: "ArrowLeft"})
        })
        this.rightBtn.addEventListener("click", () => {
            this.keydownHandler({key: "ArrowRight"})
        })

        this.run()
    }

    // 键盘按下的响应函数
    keydownHandler(event: { key: string }) {
        // 需要检检查 event.key 是否合法（用户是否按了正确的按钮）
        // 修改 direction 熟悉
        this.direction = event.key;
    }


    /*
    *   让蛇移动
    *       根据方向（this.direction）使蛇移动
    *           向上  top  减少
    *           向下  top  增加
    *           向左  left 减少
    *           向右  left 增加
     */
    run() {
        // 获取蛇现在的坐标
        let X = this.snake.X;
        let Y = this.snake.Y;
        switch (this.direction) {
            case 'ArrowUp':
            case 'Up':
                // 向上移动  top  减少
                Y -= 10
                break;
            case 'ArrowDown':
            case 'Down':
                // 向下移动  top  增加
                Y += 10
                break;
            case 'ArrowLeft':
            case 'Left':
                // 向左移动  Left  减少
                X -= 10
                break;
            case 'ArrowRight':
            case 'Right':
                // 向左移动  Left  增加
                X += 10
                break;
        }

        this.checkEat(X, Y)

        // 修改蛇的 X 坐标和 Y 坐标
        try {
            this.snake.X = X;
            this.snake.Y = Y;
        } catch (e) {
            // 进入，表明出现异常。游戏结束，弹出提示信息
            alert(e.message + "游戏结束!");
            // 将 isLive 设置为 false
            this.isLive = false;
            location.reload();
        }

        this.isLive && setTimeout(this.run.bind(this), 300 - (this.scorePanel.level - 1) * 30)
    }

    // 检查蛇是否吃到食物
    checkEat(X: number, Y: number) {
        if (X === this.food.X && Y === this.food.Y) {
            console.log("吃到食物了");
            // 重置食物位置
            this.food.change();
            // 加分
            this.scorePanel.addScore();
            // 蛇加一节
            this.snake.addBody();
        }
    }
}

export default GameControl;